package cn.sc.summer.mybatis.config.datasource;

import cn.hutool.extra.spring.SpringUtil;
import cn.sc.summer.mybatis.context.DynamicDataSourceContext;
import cn.sc.summer.constant.mybatisplus.datasource.DataSourceConstant;
import cn.sc.summer.exception.enums.CommonExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 类名：读写分离配置
 *
 * @author a-xin
 * @date 2024/7/30 13:19
 */
@Slf4j
@Configuration
public class ReadWriteConfig {

    @Value(value = "${mybatis-plus.read-write.read:slave}")
    private String READ;

    @Value(value = "${mybatis-plus.read-write.write:master}")
    private String WRITE;

    /**
     * 自定义读写分离配置
     */
    @Bean(name = DataSourceConstant.READ_WRITE_BEAN)
    @ConditionalOnBean(name = DataSourceConstant.DYNAMIC_DATA_SOURCE)
    @ConditionalOnProperty(prefix = "mybatis-plus.read-write", name = "enable", havingValue = "true")
    public Map<String, List<String>> checkReadWrite() {
        log.info("==>  Start initialization the read-write datasource...");
        CommonExceptionEnum.NORMAL_EXCEPTION.isBlank(READ, "Please set the read database!");
        CommonExceptionEnum.NORMAL_EXCEPTION.isBlank(WRITE, "Please set the write database!");
        String[] readDataBases = READ.split(",");
        String[] writeDataBases = WRITE.split(",");
        List<String> readDataBaseList = Arrays.stream(readDataBases).distinct().collect(Collectors.toList());
        List<String> writeDataBaseList = Arrays.stream(writeDataBases).distinct().collect(Collectors.toList());

        Stream<String> allDataBase = Stream.concat(readDataBaseList.stream(), writeDataBaseList.stream());
        DynamicDataSourceContext dynamicDataSourceContext = SpringUtil.getBean(DataSourceConstant.DYNAMIC_DATA_SOURCE, DynamicDataSourceContext.class);
        Map<Object, Object> targetDataSources = dynamicDataSourceContext.getTargetDataSources();
        allDataBase.forEach(item -> {
            if (!targetDataSources.containsKey(item)) {
                throw new IllegalArgumentException("The specified data source: [" + item + "] does not exist");
            }
        });

        Map<String, List<String>> resultMap = new HashMap<>();
        resultMap.put(DataSourceConstant.READ_DATABASE, readDataBaseList);
        resultMap.put(DataSourceConstant.WRITE_DATABASE, writeDataBaseList);
        return resultMap;
    }

}
